#coding=utf-8

import io
import os
import sys
import json

import sys
import yaml
import shutil

from xml.etree import ElementTree
import plistlib

from PIL import Image

from .AtlasInfo import AtlasInfo


from clitool.core.task.spine.SpineBaseTask import SpineBaseTask

class ExportSpineTask(SpineBaseTask):

    def __init__(self, options):
        super(ExportSpineTask, self).__init__(options)
        self._atlas_struct = {}
        self._attachment_list = []
        self._tmpCropTmpPaths = []
        self._atlasInfoList = []
        self.flag = False

    def __start(self):
        pass

    def __finish(self, error):
        pass

    def __run(self):
        self.___parseAllSpines()

    def ___parseAllSpines(self):
        all_files = []
        for sub_folder in os.listdir(self.getInputPath()):
            full_path = os.path.join(self.getInputPath(), sub_folder)
            if not os.path.isfile(full_path) and sub_folder != '__tmp':
                atlas_file = os.path.join(full_path, sub_folder + '.atlas')
                png_file = os.path.join(full_path, sub_folder + '.png')
                skel_file = os.path.join(full_path, sub_folder + '.skel')
                all_files.append({'atlas':atlas_file, 'png':png_file, 'skel':skel_file, 'full_path':full_path, 'spine_name': sub_folder})

        total = len(all_files)

        # 拆图 start
        self.startProcess(total)

        for i in range(0, total):
            file_dict = all_files[i]

            self.updateProcess(i, 'export spine ' + file_dict['spine_name'])
            
            # 大图
            self._img = Image.open(file_dict['png'])

            # atlas
            atlasInfo = AtlasInfo()
            atlasInfo.initWithAtlas(file_dict['atlas'])
            self._atlasInfoList.append(atlasInfo)

            # 裁剪后保存路径
            cropPath = self.__getTmpCropPath(file_dict['spine_name'])
            self._tmpCropTmpPaths.append(cropPath)

            for pngInfo in atlasInfo.pictures:
                self.___splitPng2(pngInfo, cropPath)

        self.finishProcess() 
        
        # 合图
        #tmpPackupPath = self.__getPackupPath()
        cmd = self.get_config('TexturePacker') + ' --sheet ' + os.path.join(self.getOutputPath(), 'alltextures.png')
        cmd = cmd + ' --data ' + os.path.join(self.getOutputPath(), 'alltextures.plist')
        cmd = cmd + ' --opt RGBA8888 --size-constraints NPOT --format cocos2d --border-padding 2 --shape-padding 2'

        for imgPath in self._tmpCropTmpPaths:
            
            for f in os.listdir(imgPath):
                fPath = os.path.join(imgPath, f)
                # print('================ ', fPath)
                if os.path.isfile(fPath):
                    ext = os.path.splitext(f)[1]
                    if ext == '.png' or ext == '.jpg':
                        cmd = cmd + ' ' + fPath
        os.system(cmd)

        # src_file = os.path.join(tmpPackupPath, 'alltextures.png')
        # dst_file = os.path.join(self.getOutputPath(), 'alltextures.png')
        # print('dst:', dst_file)
        # shutil.copy(src_file, dst_file)

        for i in range(0, total):
            file_dict = all_files[i]
            #shutil.copy(file_dict['atlas'], os.path.join(self.getOutputPath(), file_dict['spine_name'] + '.atlas'))
            shutil.copy(file_dict['skel'], os.path.join(self.getOutputPath(), file_dict['spine_name'] + '.skel'))


        # 重构Atlas
        allTexturePath = os.path.join(self.getOutputPath(), 'alltextures.plist')

        plistfile = io.open(allTexturePath, 'rb')
        # plistStr = plistfile.read()
        # print('++++++++++', plistStr)
        # plistfile.close()

        # root = ElementTree.parse(allTexturePath)

        # plist_dict = self.___tree2dict(root[0])
        # print('xxxxxxxxxxxxxxxxxxxxx2')

        plist_dict = plistlib.load(plistfile)
        for atlasInfo in self._atlasInfoList:
            atlasInfo.readFrom(plist_dict)
            atlasInfo.save(self.getOutputPath())

        plistfile.close()

        # for i in range(0, total):
        #     self.flag = False
            # self._atlas_struct = {}
            # self._attachment_list = []

            # if os.path.exists(file_dict['atlas']):
            #     # 打开文件
            #     f = io.open(file_dict['atlas'], 'r', encoding = 'utf-8')
            #     for line in f.readlines():
            #         # print("parse =========: %s" % line)

            #         data = ''.join(line.split()) #去掉空格
            #         if self.flag == False:
            #             self.___parseAtlas(data)
            #         else:
            #             self.___parseAttachment(data)
            
            #     # 拆解图
            #     self.___splitPng(file_dict['spine_name'])

            #     f.close() 


        
                

    def ___tree2dict(self, tree):
        plist_dict = {}
        for index, item in enumerate(tree):
            if item.tag == 'key':
                key = item.text

                if tree[index + 1].tag == 'string':
                    plist_dict[key] = tree[index + 1].text
                elif tree[index + 1].tag == 'integer':
                    plist_dict[key] = tree[index + 1].text
                elif tree[index + 1].tag == 'true':
                    plist_dict[key] = True
                elif tree[index + 1].tag == 'false':
                    plist_dict[key] = False
                elif tree[index + 1].tag == 'dict':
                    plist_dict[key] = self.___tree2dict(tree[index + 1])

        return plist_dict

    def ___parseAtlas(self, data):
        if data.find('.png') != -1:
            self._atlas_struct['png_name'] = data
        elif data.startswith('format'):
            self._atlas_struct['format'] = data.split(':')[-1]
        elif data.startswith('filter'):
            self._atlas_struct['filter'] = data.split(':')[-1]
        elif data.startswith('size'):
            self._atlas_struct['width']     = int(data.split(':')[-1].split(',')[0])
            self._atlas_struct['height']    = int(data.split(':')[-1].split(',')[-1])
        elif data.startswith('repeat'):
            self._atlas_struct['repeat'] = data.split(':')[-1]
            self.flag = True

    def ___parseAttachment(self, data):
        if ':' in data:
            if data.startswith('rotate'):
                if data.split(':')[-1] == 'false':
                    self._attachment_list[-1]['rotate'] = False
                else:
                    self._attachment_list[-1]['rotate'] = True
            elif data.startswith('xy'):
                self._attachment_list[-1]['x']          = int(data.split(':')[-1].split(',')[0])
                self._attachment_list[-1]['y']          = int(data.split(':')[-1].split(',')[-1])
            elif data.startswith('size'):
                self._attachment_list[-1]['width']      = int(data.split(':')[-1].split(',')[0])
                self._attachment_list[-1]['height']     = int(data.split(':')[-1].split(',')[-1])
            elif data.startswith('orig'):
                self._attachment_list[-1]['orig_w']     = int(data.split(':')[-1].split(',')[0])
                self._attachment_list[-1]['orig_h']     = int(data.split(':')[-1].split(',')[-1])
            elif data.startswith('offset'):
                self._attachment_list[-1]['offset_x']   = int(data.split(':')[-1].split(',')[0])
                self._attachment_list[-1]['offset_y']   = int(data.split(':')[-1].split(',')[-1])
            elif data.startswith('index'):
                self._attachment_list[-1]['index']      = int(data.split(':')[-1])
        else:
            newDict = {}
            newDict['name'] = data
            self._attachment_list.append(newDict)

    def ___splitPng(self, spine_name):

        # print(self._img.format, self._img.size, self._img.mode)

        for attachment in self._attachment_list:
            # print('attachment -- %s' % attachment)

            rotate = attachment['rotate']


            x = int(attachment['x'])
            y = int(attachment['y'])

            if rotate == True:
                w = int(attachment['height'])
                h = int(attachment['width'])
            else:
                w = int(attachment['width'])
                h = int(attachment['height'])


            region = (x, y, x + w, y + h)
            # print('x = %d  y = %d  w = %d  h = %d' % (x, y, w, h))

            cropImg = self._img.crop(region)
            # print(cropImg)
            if rotate == True:
                cropImg = cropImg.transpose(Image.ROTATE_270)
            else:
                pass

            # 原始宽高以及透明裁剪偏移
            orig_w = attachment['orig_w']
            orig_h = attachment['orig_h']
            offset_x = attachment['offset_x']
            offset_y = attachment['offset_y']

            result_image = Image.new("RGBA", (orig_w, orig_h), (0,0,0,0))
            result_image.paste(cropImg, (offset_x, offset_y, offset_x + cropImg.width, offset_y + cropImg.height))

            # 裁剪后保存路径
            cropPath = os.path.join(self.getOutputPath(), spine_name)
            if not os.path.exists(cropPath):
                os.makedirs(cropPath)
            cropFile = os.path.join(cropPath, attachment['name'] + '.png')

            # 可展示
            # result_image.show()

            # print('Crop Path -- %s' % cropFile)
            result_image.save(cropFile)


    def ___splitPng2(self, pngInfo, cropPath):

        region = pngInfo.getRegion()

        # print('x = %d  y = %d  w = %d  h = %d' % (region[0], region.y, region.w, region.h))

        cropImg = self._img.crop(region)

        # print(cropImg)
        if pngInfo.rotate == True:
            cropImg = cropImg.transpose(Image.ROTATE_270)
        else:
            pass

        # 原始宽高以及透明裁剪偏移
        offset_x = pngInfo.offset[0]
        offset_y = pngInfo.offset[1]

        result_image = Image.new("RGBA", pngInfo.orig, (0,0,0,0))
        result_image.paste(cropImg, (offset_x, offset_y, offset_x + cropImg.width, offset_y + cropImg.height))
        # result_image.show() # 可展示

        
        cropFile = os.path.join(cropPath, pngInfo.name + '.png')
        
        result_image.save(cropFile)
            

    def __getTmpCropPath(self, spine_name):
        cropPath = os.path.join(self.getInputPath(), "__tmp", spine_name)
        if not os.path.exists(cropPath):
            os.makedirs(cropPath)
        return cropPath

    def __getPackupPath(self):
        packupPath = os.path.join(self.getInputPath(), "__tmp")
        if not os.path.exists(packupPath):
            os.makedirs(packupPath)
        return packupPath

    def run(self):
        self.__start()
        try:
            self.__run()
            self.__finish(0)
        except Exception:
            self.__finish(-1)